home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xinvaders / vaders.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  11.2 KB  |  492 lines

  1. /* 
  2. Copyright notice:
  3.  
  4. This is mine.  I'm only letting you use it.  Period.  Feel free to rip off
  5. any of the code you see fit, but have the courtesy to give me credit.
  6. Otherwise great hairy beasties will rip your eyes out and eat your flesh
  7. when you least expect it.
  8.  
  9. Jonny Goldman <jonathan@think.com>
  10.  
  11. Wed May  8 1991
  12. */
  13.  
  14. /* vaders.c - handle movement, etc. of the vaders. */
  15.  
  16. #include "vaders.h"
  17.  
  18. #define NUMTYPES    3    /* How many types of vaders there are. */
  19. #define NUMROWS        5    /* number of rows of vaders */
  20. #define NUMVADERS    11    /* Maximum of vaders of each type. */
  21. #define BASEY 10
  22. #define VADERWIDTH    (14*scale)
  23. #define VADERHEIGHT    (12*scale)
  24. #define VADERYINC    (8*scale)
  25.  
  26. static XImage *Vader_Image[NUMTYPES][2];    /* XImages for the vaders. */
  27.  
  28. extern int basex;        /* Base location */
  29.  
  30. static int tick = 0;
  31. static int vaderwaitinit;
  32.  
  33. typedef struct _VaderRec {
  34.   int x, y;            /* Location. */
  35.   int vx, vy;            /* Velocity. */
  36.   int width, height;        /* size of this Vader. */
  37.   GC gc;            /* graphics context */
  38.   XImage *shape_image[2];
  39.   int value;
  40.   Boolean alive;
  41.   Boolean exploded;
  42. } VaderRec, *Vader;
  43.  
  44. VaderRec vaders[NUMROWS][NUMVADERS];
  45.  
  46. int numvaders = 0;        /* Number of vaders existing. */
  47.  
  48.  
  49. typedef struct _BaseRec {
  50.   int x;            /* Location. */
  51.   int v;            /* velocity */
  52.   int width, height;        /* box of this base. */
  53.   XImage *shape_image;        /* an XImage for the spaceship */
  54. } BaseRec, *Base;
  55.  
  56. extern Base base;
  57.  
  58. XImage *Explode_image;
  59.  
  60. /* indicates pad around vader bitmap for better collision detection */
  61. #define VADERPAD     scale
  62.  
  63. #define PointInVader(vader, x, y)    \
  64.   (x >= (vader)->x+VADERPAD && y >= (vader)->y &&        \
  65.    x <= (vader)->x + (vader)->width-VADERPAD  && y <= (vader)->y + (vader)->height)
  66.  
  67. static void PaintVader(vader, gc)
  68.      Vader vader;
  69.      GC gc;
  70. {
  71.   int rx, ry, w, h;
  72.   
  73.   w = vader->width;
  74.   h = vader->height;
  75.  
  76.   rx = vader->x;
  77.   ry = vader->y;
  78.   
  79.   XPutImage(dpy, gamewindow, gc, vader->shape_image[tick],
  80.         0, 0, rx, ry, w, h);
  81. }
  82.  
  83. static void PaintExplodedVader(vader, gc)
  84.      Vader vader;
  85.      GC gc;
  86. {
  87.   int rx, ry, w, h;
  88.   
  89.   w = Explode_image->width;
  90.   h = Explode_image->height;
  91.  
  92.   rx = vader->x;
  93.   ry = vader->y;
  94.   
  95.   XPutImage(dpy, gamewindow, gc, Explode_image,
  96.         0, 0, rx, ry, w, h);
  97. }
  98.  
  99. static void DestroyVader(vader)
  100. Vader vader;
  101. {
  102.   PaintVader(vader, backgc);
  103.   score += vader->value;
  104.   PaintScore();
  105.   numvaders--;
  106.   switch (numvaders) {
  107.   case 32:
  108.   case 16:
  109.   case 8:
  110.   case 4:
  111.   case 2:
  112.   case 1:
  113.     vaderwait /= 2; break;
  114.   }
  115.   vader->alive = FALSE;
  116.   vader->exploded = TRUE;
  117.   PaintExplodedVader(vader, vader->gc);
  118. }
  119.  
  120.  
  121.  
  122. Boolean ShotHitsVader(x, y)
  123.      int x, y;
  124. {
  125.   register Vader vader;
  126.   int i, j;
  127.  
  128.   for(j = 0; j < NUMROWS; j++)
  129.     for (i=0 ; i<NUMVADERS ; i++) {
  130.       vader = &vaders[j][i];
  131.       if(vader->alive && PointInVader(vader, x, y)) {
  132.     DestroyVader(vader);
  133.     return TRUE;
  134.     }
  135.   }
  136.   return FALSE;
  137. }
  138.  
  139.  
  140.  
  141. void PaintAllVaders()
  142. {
  143.   int i, j;
  144.   Vader vader;
  145.  
  146.   for(j = 0; j < NUMROWS; j++)
  147.     for (i=0 ; i< NUMVADERS ; i++) {
  148.       vader = &vaders[j][i];
  149.       if(vader->alive) PaintVader(vader, vader->gc);
  150.     }
  151. }
  152.  
  153. /* add some random shot */
  154.  
  155. void SFire()
  156. {
  157.   register Vader vader;
  158.   int i, j, c;
  159.  
  160.   for(j = 0, c = random()%NUMVADERS; j < NUMVADERS; j++) {
  161.     for (i= NUMROWS-1; i>=0; i--) {
  162.       vader = &vaders[i][(c+j)%NUMVADERS];
  163.       if(vader->alive) {
  164.     AddVshot(vader->x+vader->width/2, vader->y+vader->height);
  165.     return;
  166.       }
  167.     }
  168.   }
  169. }
  170.  
  171. void VaderBoop(tick)
  172. int tick;
  173. {
  174.   XKeyboardControl vals;
  175.  
  176.   vals.bell_duration = vaderwait/2;
  177.   vals.bell_pitch = tick ? 60 : 40;
  178.  
  179.   XChangeKeyboardControl(dpy, KBBellPitch | KBBellDuration, &vals);
  180.   XBell(dpy, 100);
  181. }
  182.  
  183. static int createvaderp = FALSE;
  184.  
  185. /*ARGSUSED*/
  186. void MoveVaders(closure, id)
  187.      Opaque closure;
  188.      XtIntervalId id;
  189. {
  190.   register Vader vader;
  191.   register int i, j;
  192.   Boolean reversep;
  193.  
  194.   reversep = FALSE;
  195.  
  196.   if (closure != (Opaque) MoveVaders) return;
  197.   if (createvaderp) {
  198.     createvaderp = FALSE;
  199.     CreateVaders(level);
  200.   }
  201.   if (numvaders == 0 && numvshots == 0) {
  202.     vadertimerid = XtAddTimeOut(2000, MoveVaders, (Opaque) MoveVaders);
  203.     level++;
  204.     createvaderp = TRUE;
  205.     InitBuildings();
  206.     DrawBuildings();
  207.   } else {
  208.     vadertimerid = XtAddTimeOut(vaderwait, MoveVaders, (Opaque) MoveVaders);
  209.     /* this is the way to do it, but on the Sun it SUCKS!
  210.     VaderBoop(tick);
  211.     */
  212.     if((random()%1000)>900) SFire();
  213.     for(j = 0; j < NUMROWS; j++)
  214.       for (i=0 ; i< NUMVADERS ; i++) {
  215.     vader = &vaders[j][i];
  216.     if (vader->exploded) {
  217.       PaintExplodedVader(vader, backgc);
  218.       vader->exploded = FALSE;
  219.     }
  220.     else if (vader->alive) {
  221.       if (vader->vx > 0)
  222.         (void)ShotHitsBuilding(vader->x+vader->width, vader->y+vader->height);
  223.       else
  224.         (void)ShotHitsBuilding(vader->x, vader->y+vader->height);
  225.       vader->x += vader->vx;
  226.       if ((vader->x < (VADERWIDTH-vader->width)/2 && vader->vx < 0) || 
  227.           (vader->x > gamewidth-VADERWIDTH && vader->vx > 0))
  228.         reversep = TRUE;
  229.       tick = tick ? 0 : 1;
  230.       PaintVader(vader, vader->gc);
  231.       tick = tick ? 0 : 1;
  232.     }
  233.       }
  234.     tick = tick ? 0 : 1;
  235.     if (reversep) {
  236.       for(j = 0; j < NUMROWS; j++)
  237.     for (i=0 ; i< NUMVADERS ; i++) {
  238.       vader = &vaders[j][i];
  239.       if (vader->alive) {
  240.         PaintVader(vader, backgc);
  241.         vader->vx = -vader->vx;
  242.         vader->y = vader->y + VADERYINC;
  243.         PaintVader(vader, vader->gc);
  244.         if(vader->y >= gameheight-base->height+vader->height) {
  245.           ResetGame();
  246.           return;
  247.         }
  248.       }
  249.     }
  250.     }
  251.   }
  252. }
  253.  
  254. #include "vader1a1.bit"
  255. #include "vader1b1.bit"
  256. #include "vader1a2.bit"
  257. #include "vader1b2.bit"
  258. #include "vader2a1.bit"
  259. #include "vader2b1.bit"
  260. #include "vader2a2.bit"
  261. #include "vader2b2.bit"
  262. #include "vader3a1.bit"
  263. #include "vader3b1.bit"
  264. #include "vader3a2.bit"
  265. #include "vader3b2.bit"
  266. #include "vexplod1.bit"
  267. #include "vexplod2.bit"
  268.  
  269. int ReadVaderImages()
  270. {
  271.   if (scale == 1) {
  272.     Vader_Image[0][0] = XCreateImage(dpy,
  273.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  274.                      1,
  275.                      XYBitmap,
  276.                      0,
  277.                      vader1a1_bits,
  278.                      vader1a1_width, vader1a1_height,
  279.                      8, 0);
  280.     Vader_Image[0][0]->bitmap_bit_order = LSBFirst;
  281.     Vader_Image[0][0]->byte_order = LSBFirst;
  282.  
  283.     Vader_Image[0][1] = XCreateImage(dpy,
  284.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  285.                      1,
  286.                      XYBitmap,
  287.                      0,
  288.                      vader1b1_bits,
  289.                      vader1b1_width, vader1b1_height,
  290.                      8, 0);
  291.     Vader_Image[0][1]->bitmap_bit_order = LSBFirst;
  292.     Vader_Image[0][1]->byte_order = LSBFirst;
  293.  
  294.     Vader_Image[1][0] = XCreateImage(dpy,
  295.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  296.                      1,
  297.                      XYBitmap,
  298.                      0,
  299.                      vader2a1_bits,
  300.                      vader2a1_width, vader2a1_height,
  301.                      8, 0);
  302.     Vader_Image[1][0]->bitmap_bit_order = LSBFirst;
  303.     Vader_Image[1][0]->byte_order = LSBFirst;
  304.  
  305.     Vader_Image[1][1] = XCreateImage(dpy,
  306.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  307.                      1,
  308.                      XYBitmap,
  309.                      0,
  310.                      vader2b1_bits,
  311.                      vader2b1_width, vader2b1_height,
  312.                      8, 0);
  313.     Vader_Image[1][1]->bitmap_bit_order = LSBFirst;
  314.     Vader_Image[1][1]->byte_order = LSBFirst;
  315.  
  316.     Vader_Image[2][0] = XCreateImage(dpy,
  317.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  318.                      1,
  319.                      XYBitmap,
  320.                      0,
  321.                      vader3a1_bits,
  322.                      vader3a1_width, vader3a1_height,
  323.                      8, 0);
  324.     Vader_Image[2][0]->bitmap_bit_order = LSBFirst;
  325.     Vader_Image[2][0]->byte_order = LSBFirst;
  326.  
  327.     Vader_Image[2][1] = XCreateImage(dpy,
  328.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  329.                      1,
  330.                      XYBitmap,
  331.                      0,
  332.                      vader3b1_bits,
  333.                      vader3b1_width, vader3b1_height,
  334.                      8, 0);
  335.     Vader_Image[2][1]->bitmap_bit_order = LSBFirst;
  336.     Vader_Image[2][1]->byte_order = LSBFirst;
  337.  
  338.     Explode_image = XCreateImage(dpy,
  339.                  DefaultVisual(dpy, DefaultScreen(dpy)),
  340.                  1,
  341.                  XYBitmap,
  342.                  0,
  343.                  vexplode1_bits,
  344.                  vexplode1_width, vexplode1_height,
  345.                  8, 0);
  346.  
  347.     Explode_image->bitmap_bit_order = LSBFirst;
  348.     Explode_image->byte_order = LSBFirst;
  349.   }
  350.   else {
  351.     Vader_Image[0][0] = XCreateImage(dpy,
  352.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  353.                      1,
  354.                      XYBitmap,
  355.                      0,
  356.                      vader1a2_bits,
  357.                      vader1a2_width, vader1a2_height,
  358.                      8, 0);
  359.     Vader_Image[0][0]->bitmap_bit_order = LSBFirst;
  360.     Vader_Image[0][0]->byte_order = LSBFirst;
  361.  
  362.     Vader_Image[0][1] = XCreateImage(dpy,
  363.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  364.                      1,
  365.                      XYBitmap,
  366.                      0,
  367.                      vader1b2_bits,
  368.                      vader1b2_width, vader1b2_height,
  369.                      8, 0);
  370.     Vader_Image[0][1]->bitmap_bit_order = LSBFirst;
  371.     Vader_Image[0][1]->byte_order = LSBFirst;
  372.  
  373.     Vader_Image[1][0] = XCreateImage(dpy,
  374.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  375.                      1,
  376.                      XYBitmap,
  377.                      0,
  378.                      vader2a2_bits,
  379.                      vader2a2_width, vader2a2_height,
  380.                      8, 0);
  381.     Vader_Image[1][0]->bitmap_bit_order = LSBFirst;
  382.     Vader_Image[1][0]->byte_order = LSBFirst;
  383.  
  384.     Vader_Image[1][1] = XCreateImage(dpy,
  385.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  386.                      1,
  387.                      XYBitmap,
  388.                      0,
  389.                      vader2b2_bits,
  390.                      vader2b2_width, vader2b2_height,
  391.                      8, 0);
  392.     Vader_Image[1][1]->bitmap_bit_order = LSBFirst;
  393.     Vader_Image[1][1]->byte_order = LSBFirst;
  394.  
  395.     Vader_Image[2][0] = XCreateImage(dpy,
  396.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  397.                      1,
  398.                      XYBitmap,
  399.                      0,
  400.                      vader3a2_bits,
  401.                      vader3a2_width, vader3a2_height,
  402.                      8, 0);
  403.     Vader_Image[2][0]->bitmap_bit_order = LSBFirst;
  404.     Vader_Image[2][0]->byte_order = LSBFirst;
  405.  
  406.     Vader_Image[2][1] = XCreateImage(dpy,
  407.                      DefaultVisual(dpy, DefaultScreen(dpy)),
  408.                      1,
  409.                      XYBitmap,
  410.                      0,
  411.                      vader3b2_bits,
  412.                      vader3b2_width, vader3b2_height,
  413.                      8, 0);
  414.     Vader_Image[2][1]->bitmap_bit_order = LSBFirst;
  415.     Vader_Image[2][1]->byte_order = LSBFirst;
  416.  
  417.     Explode_image = XCreateImage(dpy,
  418.                  DefaultVisual(dpy, DefaultScreen(dpy)),
  419.                  1,
  420.                  XYBitmap,
  421.                  0,
  422.                  vexplode2_bits,
  423.                  vexplode2_width, vexplode2_height,
  424.                  8, 0);
  425.  
  426.     Explode_image->bitmap_bit_order = LSBFirst;
  427.     Explode_image->byte_order = LSBFirst;
  428.   }
  429.  
  430.   return BitmapSuccess;
  431. }
  432.  
  433.  
  434. void CreateVaders(level)
  435. int level;
  436. {
  437.   int offset, i, j;
  438.   Vader vader;
  439.  
  440.   offset = MIN(level, 8);
  441.   vaderwait = vaderwaitinit;
  442.   numvaders = NUMROWS*NUMVADERS;
  443.   for (j = 0; j < NUMROWS; j++)
  444.     for (i = 0; i < NUMVADERS; i++) {
  445.       vader = &vaders[j][i];
  446.       vader->x = 3 + VADERWIDTH*i+(VADERWIDTH-vader->width)/2;
  447.       vader->y = VADERHEIGHT*(offset+j);
  448.       vader->vx = scale;
  449.       vader->alive = TRUE;
  450.       vader->exploded = FALSE;
  451.     }
  452. }
  453.  
  454. void InitVaders()
  455. {
  456.   int i, j, k, width, height;
  457.   Vader vader;
  458.  
  459.   level = 1;
  460.   if (ReadVaderImages() != BitmapSuccess) {
  461.     fprintf(stderr, "Error reading Invader images\n");
  462.     exit(10);
  463.   }
  464.  
  465.   for (j = 0; j < NUMROWS; j++) {
  466.     switch (j) {
  467.     case 0:
  468.       k = 0; break;
  469.     case 1:
  470.     case 2:
  471.       k = 1; break;
  472.     case 3:
  473.     case 4:
  474.       k = 2; break;
  475.     }
  476.     width = Vader_Image[k][0]->width;
  477.     height = Vader_Image[k][0]->height;
  478.     for (i = 0; i < NUMVADERS; i++) {
  479.       vader = &vaders[j][i];
  480.       vader->shape_image[0] = Vader_Image[k][0];
  481.       vader->shape_image[1] = Vader_Image[k][1];
  482.       vader->gc = vadergc[k];
  483.       vader->width = width;
  484.       vader->height = height;
  485.       vader->value = 10*(3-k);
  486.     }
  487.   }
  488.   vaderwaitinit = vaderwait;
  489.   CreateVaders(level);
  490.   vadertimerid = NULL;
  491. }
  492.